package com.qunar.wan.service;

import com.qunar.wan.common_api.model.Activity;
import com.qunar.wan.common_api.model.ActivityIndex;
import com.qunar.wan.common_api.model.SearchResult;
import com.qunar.wan.common_api.model.enums.ActivityState;
import com.qunar.wan.common_api.service.ActivityService;
import com.qunar.wan.common_api.service.ConvertService;
import com.qunar.wan.common_api.service.LuceneSearchService;
import com.qunar.wan.support.lucene.CommonSearcher;
import com.qunar.wan.support.lucene.DocumentWriter;
import com.qunar.wan.support.lucene.LuceneContext;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Sort;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.Future;

/**
 * User: cyoung Date: 12/3/13 Time: 5:25 PM
 */
@Service("activitySearchService")
public class ActivitySearchImpl extends CommonSearcher<Activity, ActivityIndex> implements
        LuceneSearchService<Activity> {
    @Resource
    private ConvertService activityConvertService;
    @Resource
    private ActivityService activityService;

    @Override
    public SearchResult search(String keywords, int pageSize, int pageNum) {
        SearchResult searchResult = null;
        try {
            searchResult = super.search(keywords, pageSize, pageNum);
        } catch (Exception e) {
            logger.error("搜索\"{}\"异常.", keywords, e);
        }
        return searchResult;
    }

    @Override
    public ConvertService getConvertService() {
        return activityConvertService;
    }

    @Override
    public Sort getSortRules() {
        // return new org.apache.lucene.search.Sort(new SortField[]{new SortField("start",
        // SortField.Type.LONG, false)});
        return null;
    }

    @Async
    public Future<Boolean> addIndexDoc(Activity activity) {
        long start = System.currentTimeMillis();
        try {
            super.addIndexDoc(activity);
        } catch (IOException e) {
            logger.error("创建搜索索引失败(Title:{})", activity.getTitle(), e);
            return new AsyncResult<Boolean>(false);
        }
        logger.info("创建搜索索引(Title:{})耗时:{}ms", activity.getTitle(), System.currentTimeMillis() - start);
        return new AsyncResult<Boolean>(true);
    }

    @Override
    public Query buildQuery(String queryString) throws ParseException {
        queryString = QueryParser.escape(queryString);
        Map<String, Float> termBoosts = new LinkedHashMap<String, Float>(3);
        termBoosts.put("title", 3.0f);
        termBoosts.put("place", 2.0f);
        termBoosts.put("summary", 1.5f);
        String[] parseFields = new String[] { "title", "place", "summary" };
        MultiFieldQueryParser multiFieldQueryParser = new MultiFieldQueryParser(LuceneContext.getVersion(),
                parseFields, LuceneContext.getAnalyzer(), termBoosts);
        return multiFieldQueryParser.parse(queryString);
    }

    @Override
    public void reIndexAll() throws IOException {
        DocumentWriter.addIndexDocs(activityConvertService,
                activityService.selectByQuery(new com.qunar.wan.common_api.model.Query("state",
                        ActivityState.CHECK_SUCCESS)));
        LuceneContext.getIndexWriter().forceMerge(3);
        LuceneContext.getIndexWriter().commit();
    }
}
